package com.study.chess;

import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.Scanner;

/**
 * 五子棋游戏
 */
public class Gomoku {
    // 棋盘大小
    private static final int SIZE = 15;
    // 空位标记
    private static final char EMPTY = '·';
    // 黑棋标记
    private static final char BLACK = '●';
    // 白棋标记
    private static final char WHITE = '○';
    // 棋盘数组
    private static char[][] board = new char[SIZE][SIZE];
    // 当前玩家标记
    private static char currentPlayer = BLACK;

    /**
     * 主程序入口
     */
    public static void main(String[] args) {
        // 初始化棋盘
        initializeBoard();
        // 打印初始棋盘
        printBoard();

        // 使用try-with-resources确保scanner在使用后正确关闭
        try (Scanner scanner = new Scanner(System.in)) {
            while (true) {
                try {
                    // 提示玩家输入
                    System.out.print("玩家 " + (currentPlayer == BLACK ? "黑" : "白")
                            + "方，输入行列（1-15，如 8 8）: ");
                    // 读取玩家输入
                    int row = scanner.nextInt() - 1;
                    int col = scanner.nextInt() - 1;

                    // 检查落子是否有效
                    if (isValidMove(row, col)) {
                        // 落子
                        board[row][col] = currentPlayer;
                        // 打印更新后的棋盘
                        printBoard();

                        // 检查是否获胜
                        if (checkWin(row, col)) {
                            // 宣布获胜者
                            System.out.println("玩家 " + (currentPlayer == BLACK ? "黑" : "白") + "方获胜！");
                            break;
                        }

                        // 检查是否平局
                        if (isBoardFull()) {
                            System.out.println("平局！");
                            break;
                        }

                        // 切换玩家
                        currentPlayer = (currentPlayer == BLACK) ? WHITE : BLACK;
                    } else {
                        System.out.println("无效落子，请重新输入！");
                    }
                } catch (InputMismatchException e) {
                    // 处理无效输入
                    System.out.println("请输入有效的数字！");
                    scanner.nextLine(); // 清除无效输入
                }
            }
        }
    }

    /**
     * 初始化棋盘为全空
     */
    private static void initializeBoard() {
        for (char[] row : board) {
            Arrays.fill(row, EMPTY);
        }
    }

    /**
     * 打印棋盘状态
     */
    private static void printBoard() {
        // 打印列号
        System.out.print("   ");
        for (int i = 0; i < SIZE; i++) {
            System.out.printf("%2d ", i + 1);
        }
        System.out.println();

        // 打印棋盘
        for (int i = 0; i < SIZE; i++) {
            System.out.printf("%2d ", i + 1);
            for (int j = 0; j < SIZE; j++) {
                System.out.print(" " + board[i][j] + " ");
            }
            System.out.println();
        }
    }

    /**
     * 检查落子位置是否有效
     *
     * @param row 行号
     * @param col 列号
     * @return 是否有效
     */
    private static boolean isValidMove(int row, int col) {
        return row >= 0 && row < SIZE && col >= 0 && col < SIZE && board[row][col] == EMPTY;
    }

    /**
     * 检查是否获胜
     *
     * @param row 最新落子的行号
     * @param col 最新落子的列号
     * @return 是否获胜
     */
    private static boolean checkWin(int row, int col) {
        int[][] directions = {{0, 1}, {1, 0}, {1, 1}, {1, -1}}; // 水平、垂直、对角线

        for (int[] dir : directions) {
            int count = 1;

            // 正方向检查
            int x = row + dir[0];
            int y = col + dir[1];
            while (x >= 0 && x < SIZE && y >= 0 && y < SIZE && board[x][y] == currentPlayer) {
                count++;
                x += dir[0];
                y += dir[1];
            }

            // 反方向检查
            x = row - dir[0];
            y = col - dir[1];
            while (x >= 0 && x < SIZE && y >= 0 && y < SIZE && board[x][y] == currentPlayer) {
                count++;
                x -= dir[0];
                y -= dir[1];
            }

            if (count >= 5) return true;
        }
        return false;
    }

    /**
     * 检查棋盘是否已满
     *
     * @return 是否已满
     */
    private static boolean isBoardFull() {
        for (char[] row : board) {
            for (char cell : row) {
                if (cell == EMPTY) return false;
            }
        }
        return true;
    }
}
